#!/usr/bin/python

from sys import exit, argv, stderr
from os import system, popen

if(len(argv) < 5):
    print """usage: %s ip/mask bssid router power
    """ % argv[0]
    exit(-1)

prefixip=str(argv[1])
ip=prefixip.split('/')[0]
bssid=str(argv[2])
router=str(argv[3])
power=str(argv[4])

# First, configure the device in raw/monitor mode. 
dev = 'wifi0'
rawdev = 'ath0'
channel= '4'

#ifconfig %(rawdev)s down
#ifconfig %(dev)s down
#wlanconfig %(rawdev)s destroy
#wlanconfig %(rawdev)s create wlandev %(dev)s wlanmode monitor 2> /dev/null > /dev/null

system("""
iwpriv %(rawdev)s mode 11b;  
ifconfig %(rawdev)s down;
sleep 1;
ifconfig %(dev)s down;
sleep 1;
wlanconfig %(rawdev)s destroy;
sleep 1;
wlanconfig %(rawdev)s create wlandev %(dev)s wlanmode monitor 2> /dev/null > /dev/null;
iwpriv %(rawdev)s mode 11b;
iwconfig %(rawdev)s channel %(channel)s;
echo '801' > /proc/sys/net/ath0/dev_type;
ifconfig %(dev)s up txqueuelen 1;
sleep 1;
ifconfig %(rawdev)s up txqueuelen 1 mtu 1600;
""" % globals())

decap = decapfbk = 'AthdescDecap'
encap = 'AthdescEncap'

# obtain MAC address from device
p = popen('ifconfig %(rawdev)s 2>&1'  % globals())
ifconfig = p.readline().split()
if('not' in ifconfig):
    print >> stderr, 'device not found?', ' '.join(ifconfig)
    exit(-1)
mac = ifconfig[4]
p.close()

mac = mac.split(':')
if(len(mac) < 6):
    mac = mac[0].split('-')
if(len(mac) < 6):
    print >> stderr, 'got invalid mac address!', mac
    exit(-1)

# take only 6 bytes for MAC
machex=''.join(mac[0:6])
mac = ':'.join(mac[0:6])

print >> stderr, "using %(dev)s / %(rawdev)s MAC %(mac)s" % globals()

print """
AddressInfo(sta_info %(prefixip)s %(mac)s,bssid_info %(bssid)s);

wireless_info::WirelessInfo(SSID "",BSSID bssid_info,CHANNEL %(channel)s);

control::ControlSocket("TCP",6777);

chatter::ChatterSocket("TCP",6778);

wifi_cl::Classifier(0/08%%0c 1/00%%03,    //is 802.11 node data frame
            0/04%%0c,        //is control frame
            );

dev_net_cl::Classifier(    12/0806 20/0001,    //ARP requests
            12/0806 20/0002,    //ARP replies
            12/0800,        //IP packets
            -);
            
host_net_cl::Classifier(12/0806 20/0001,    
            12/0800,    //IP packets
            );
            
dev_eth_cl::HostEtherFilter(sta_info);

host_eth_cl::HostEtherFilter(sta_info);

dev_arp_querier::ARPQuerier(sta_info);

dev_arpre::ARPResponder(%(ip)s %(mac)s);
""" % globals()

if router!="-":
    print"""
    ip_router::RadixIPLookup(0/0 %(router)s 0);
    """ % globals()

print """
snc::SNC(ETH %(mac)s) [1]
->wifi_encap::WifiEncap(0x00,WIRELESS_INFO wireless_info)
//->q::Queue(1000)
//->set_rate::SetTXRate(22)
//->SetTXPower(%(power)s)
//->%(encap)s
->ToDevice(%(rawdev)s)-> Discard;

FromHost(sta,sta_info,ETHER sta_info,HEADROOM 60) 
->host_net_cl
->ARPResponder(0/0 0:1:1:1:1:1)
->ToHost(sta);

host_net_cl [1] -> host_eth_cl -> Discard;    //packets to this host

host_eth_cl [1]
""" % globals()

if router!="-":
    print """
    -> ip_router 
    """ % globals()

print """
-> strip::Strip(14) -> SetPacketType(OUTGOING) -> dev_arp_querier -> [1] snc;    //packets to other host

dev_arp_querier [1] -> SetPacketType(OUTGOING) -> [1] snc;

//host_net_cl [2] -> Discard;

from_dev::FromDevice(%(rawdev)s)
//-> %(decap)s
-> FilterPhyErr
-> FilterTX        //filter outgoing packets
-> WifiDupeFilter
-> wifi_cl
-> Classifier(16/000101010101)
-> snc
-> WifiDecap
-> dev_eth_cl
-> dev_net_cl
-> dev_arpre
-> SetPacketType(OUTGOING)
-> [1] snc;

wifi_cl [1] -> Classifier(4/%(machex)s) -> Discard;

dev_eth_cl [1] -> Discard;    //packets to other dev

dev_net_cl [1] -> [1] dev_arp_querier;

dev_net_cl [2] 
-> check_ip::CheckIPHeader2(OFFSET 14) 
-> ip_cl::IPClassifier(dst host==%(ip)s,
                       -
                        )-> ToHost(sta);

ip_cl [1]
""" % globals()

if router!="-":
    print """-> Discard;"""
else:
    print """-> Strip(14)-> DecIPTTL -> SetPacketType(OTHERHOST) -> dev_arp_querier;"""

print """
dev_net_cl [3] -> Discard;

""" % globals()
